
// 观察者模式：

// 定义对象之间的一种一对多的依赖关系，使得每当一个对象状态发生改变时，
// 其相关依赖对象都得到通知并被自动更新。

#include <iostream>
#include <vector>
#include <string>

using namespace std;

// 抽象观察者
class Observer
{
public:
	Observer() = default;
	// 声明响应更新方法
	virtual void update() = 0;
	virtual string getLabel() = 0;
};
 
// 具体观察者
class ConcreteObserver:public Observer
{
public:
	ConcreteObserver(){};
	ConcreteObserver(string iLabel){
		Label = iLabel;
	}
	// 实现响应更新方法
	void update(){
		// 具体操作
		cout << "lable : " << Label << endl;
	}
	string getLabel(){
		return Label;
	}
private:
	string Label;
};
 
// 抽象目标
class Subject
{
public:
	// 添加观察者
	void attach(Observer* obs){
		obsList.push_back(obs);
	}
	// 移除观察者
	void detach(Observer* obs){
		for (int i = 0; i < obsList.size(); i++){
			if(obsList[i]->getLabel() == obs->getLabel())
			{
				obsList.erase(obsList.begin() + obsList.size() - i, obsList.end());
			}
		}
	}
	// 声明通知方法
	virtual void notify() = 0;
protected:
	// 观察者列表
	vector<Observer*> obsList;
};
 
// 具体目标
class ConcreteSubject :public Subject
{
public:
	// 实现通知方法
	void notify(){
		// 具体操作
		// 遍历通知观察者对象
		for (int i = 0; i < obsList.size(); i++){
			obsList[i]->update();
		}
	}
};

// 客户端代码示例
int main()
{
	// Subject 目标
	Subject  *sub = new ConcreteSubject();
	// Observer 观察者
	Observer *obs = new ConcreteObserver("observer A");
	sub->attach(obs);
	obs = new ConcreteObserver("observer B");
	sub->attach(obs);
	obs = new ConcreteObserver("observer C");
	sub->attach(obs);
	sub->notify();
	cout << " --- 移除观察者 ---:" << endl;
	obs = new ConcreteObserver("observer B");
	sub->detach(obs);
	sub->notify();
	
	return 0;
}

